package com.vpen.iot.server;

import com.vpen.iot.server.handler.IotServerChannelInitializer;
import io.netty.bootstrap.ServerBootstrap;
import io.netty.channel.*;
import io.netty.channel.nio.NioEventLoopGroup;
import io.netty.channel.socket.nio.NioServerSocketChannel;
import io.netty.util.concurrent.DefaultThreadFactory;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

import javax.annotation.PostConstruct;
import javax.annotation.PreDestroy;

/**
 * author: Vpen
 * date: 2023/1/18 14:10
 *
 * @author Vpen
 */
@Slf4j
@Component
public class IotServer {

    @Autowired
    private  IotServerChannelInitializer initializer;

    /**
     * 端口
     */
    private int port;

    /**
     * 这里需要将worker线程组设为daemon,不然tomcat不会起来
     * **/
    private final EventLoopGroup bossGroup = new NioEventLoopGroup(1,new DefaultThreadFactory("BOSS-GROUP", true));
    private final EventLoopGroup workerGroup = new NioEventLoopGroup(4,new DefaultThreadFactory("WORKER-GROUP", false));
    private final ServerBootstrap serverBootstrap = new ServerBootstrap();


    @PostConstruct
    private void start() {
        this.port = 9999;
        this.run();
    }

    @PreDestroy
    private void destroy() {
        this.bossGroup.shutdownGracefully();
        this.workerGroup.shutdownGracefully();
    }


    public void run() {
        this.serverBootstrap
                .group(this.bossGroup, this.workerGroup)
                .channel(NioServerSocketChannel.class)
                .localAddress(this.port)
                .option(ChannelOption.SO_BACKLOG, 128)
                .childOption(ChannelOption.SO_KEEPALIVE, true)
                .childHandler(initializer)
                .bind()
                .addListener((ChannelFutureListener) channelFuture -> {
                    if (channelFuture.isSuccess()) {
                        log.info("正常：端口：{}",port);
                    } else {
                        channelFuture.cause().printStackTrace();
                        log.warn("异常");
                    }
                })
                // syncUninterruptibly()让主线程同步等待子线程结果。
                .syncUninterruptibly()
                .channel()
                // 开启了一个子线程server channel的监听器，负责监听channel是否关闭的状态
                .closeFuture();


    }
}
